#pragma once


#include <vector>
#include <memory>
#include <variant>
#include <optional>

#include "String.h"
#include "FilePosition.h"

enum class ETokenType
{
    Unknow,
 
    RENUM  ,  //RENUM
    RCLASS ,  //RCLASS
    RSTRUCT,  //RSTRUCT
    RINTERFACE, //RINTERFACE

    ROBJECT,  //ROBJECT
    RFIELD, // RFIELD
    RPROPERTY, //RPROPERTY
    RFUNCTION, //RFUNCTION
    EXPORT_API , //WHENGINE_API

    EndOfFile,
    Identifier,      // only allow '_' [a-z] [A-Z] [0-9] '~'
    LiteralNumber,          // only allow [0-9] '-' '.'
    LiteralString,       
    LiteralChar,   
    LiteralBool,  
    
    CommitHead,        //"//" 
    LenEnd,            //"\n"

    //operators 
    Plus ,              //+
    PlusPlus,          //++
    Minus,              //-
    MinusMinus,         //--
    Multiply,           //*
    Divide,             // '/'
    LeftParentheses ,   //  (
    RightParentheses,   //  )
    LeftBracket ,       //  [
    RightBracket ,      //  ]
    LeftBrace,          //  {
    RightBrace,         //  }    
    Dot,                // .
    Arrow,              // ->
    Comma,              //,
    Semicolon,          // ;
    Colon,              // :
    Assign,             // =
    Mod,                // %
    And,                // &
    Xor,                // ^
    NotOperator,        // !
    Or,                 // |
    AndAnd,             // &&
    OrOr,               // ||
    Equal,              // ==
    NotEqual,           // !=
    Less,               // <
    LessEqual,          // <=
    Greater,            // >
    GreaterEqual,       // >=
    LeftShift,          // <<
    RightShift,         // >>
    PlusAssign,          // +=
    MinusAssign,        // -=
    MultiplyAssign,     // *=
    DivideAssign,       // /=
    ModAssign,          // %=
    AndAssign,          // &=
    OrAssign,           // |=
    XorAssign,          // ^=
    LeftShiftAssign,    // <<=
    RightShiftAssign,   // >>=
    Question,           // ?
    LambdaOperator,     // =>
    At,                 // @
    Tilde,              // ~

    Abstract,
 
    Break,

    Case,
    Catch,
    Class,
    Const,
    Continue,
    

    Do,
    Default,
    

    Explicit,
    Else,
    Enum,
    Extern,



    Finally,
    For,
    Foreach,

    Goto,

 
    Interface,
    If,

    Namespace,
    New,
    Nullptr,

    Operator,
    Override,

    Private,
    Protected,
    Public,

    Return,

    Sizeof,
    Static,
    Struct,
    Switch,


    This,
    Throw,
    Try,

    Virtual,
    Volatile,


    While,
  
    KeyWordMax,
};

class CToken
{
public:    
 

    CToken(ETokenType InTokenType,const SFilePosition & InFilePosition)
    {
        Type=InTokenType;

        FilePosition=InFilePosition;
    } 


    CToken(const C32String& InName,const SFilePosition & InFilePosition)
    {
        Type=ETokenType::LiteralString;
        LiteralValue=InName;

        FilePosition=InFilePosition;
    }


    CToken(double InValue,const SFilePosition & InFilePosition)
    {
        Type=ETokenType::LiteralNumber;
        LiteralValue=InValue;
        FilePosition=InFilePosition;
    }



    ETokenType Type=ETokenType::Unknow;

    std::optional<std::variant<C32String,double>> LiteralValue;

    SFilePosition FilePosition={0,0,0};

    C32String ToString() const;
};
